<template>
    <async-file-list
            :page-size="pageSize"
            @update:page-size="sizeChange"
            :label-name="labelName"
            :show-size="showSize&&fixedSize"
            :show-modify-time="showModifyTime"
            :show-operator="showOperator"
            :show-upload="showUpload"
            :show-mkdir="showMkdir"
            :show-search="showSearch"
            :show-separator="showSeparator"
            :show-type="showType&&fixedType"
            :show-description="showDescription||fixedDescription"
            :load-root-meta="loadRootMeta"
            :load-file-meta="loadFileMeta"
            :load-page="loadPage"
            :change-file-meta="changeFileMeta"
            :make-directory="mkdir"
            :upload-method="uploadMethod"
            :delete-file="deleteFile"
            :download-file="downloadFile"
            :search-files="searchFile"
            :search-meta="searchMeta"
            :table-key="tableKey"
            :search-preview="searchPreview"
            :preview-source="previewSource"
            @checkout-page="checkoutPage"
            @preview-change="$emit('preview-change', $event)"
    ></async-file-list>
</template>

<script>
    const AsyncFileList = () => import( /* webpackChunkName: "AsyncFileList" */ "~/components/file-list/AsyncFileList");
    import {getEnterpriseDetails} from "~/interface/info/EnterpriseInfo";

    /**
     * 标准文件列表 <br>
     *     此组件包含了一个 AsyncFileList 组件，将其中的参数方法通过http请求的方式实现。
     *     这个组件至少需要传入参数：loadRootUrl（根文件夹的元信息获取路径，一般为一个特殊文件夹url，如：‘/file/directory/valid-license’）
     */
    export default {
        name: "StandardFileList",
        components: {AsyncFileList},
        props:{
            /**
             * 列表名
             */
            labelName:{
                type:String,
                default:'资源'
            },
            /**
             * 是否显示文件大小
             */
            showSize:{
                type:Boolean,
                default:true
            },
            /**
             * 是否显示修改日期
             */
            showModifyTime:{
                type:Boolean,
                default:true
            },
            /**
             * 是否显示操作列表
             */
            showOperator:{
                type:Boolean,
                default:true
            },
            /**
             * 是否显示上传按钮
             */
            showUpload:{
                type:Boolean,
                default:true
            },
            /**
             * 是否显示新建文件夹按钮
             */
            showMkdir:{
                type:Boolean,
                default:true
            },
            /**
             * 是否显示搜索栏
             */
            showSearch:{
                type:Boolean,
                default:true
            },
            /**
             * 是否显示分隔符
             */
            showSeparator:{
                type:Boolean,
                default:true
            },
            /**
             * 是否显示类型
             */
            showType:{
                type:Boolean,
                default:true
            },
            /**
             * 是否显示简介
             */
            showDescription:{
                type:Boolean,
                default:false
            },
            /**
             * 获取根信息的路径
             */
            loadRootUrl:{
                type:String,
                required:true
            },
            loadPageUrl:{
                type:String,
                default:"/file/ls"
            },
            changeFileUrl:{
                type:String,
                default:"/file/mv"
            },
            makeDirectoryUrl:{
                type:String,
                default:"/file/mkdir"
            },
            uploadUrl:{
                type:String,
                default:"/file/upload"
            },
            deleteUrl:{
                type:String,
                default:"/file/rm"
            },
            downloadUrl:{
                type:String,
                default:"/file/download"
            },
            searchFilesUrl:{
                type:String,
                default:"/file/search"
            },
            searchMetaUrl:{
                type:String,
                default:"/file/search/meta"
            },
            previewSourceUrl:{
                type:String,
                default:"/file/download"
            },
            loadFileMetaUrl:{
                type:String,
                default:"/file"
            },
        },
        data(){
            return{
                fixedSize:true,
                fixedType:true,
                fixedDescription:false,
                tableKey:0,
                pageSize:12,
            }
        },
        methods:{
            sizeChange(s){
                console.log(s);
                this.$emit("update:pageSize", s);
                this.pageSize = s;
            },
            async loadRootMeta(){
                try{
                    const unitId = (await getEnterpriseDetails()).id;
                    const response = await this.$http.get(this.loadRootUrl,{params:{unitId:unitId}});
                    return response.data.parameter;
                }catch (e) {
                    console.log(e);
                    let err = e;
                    if(err.response&&err.response.hasOwnProperty("data"))err = err.response.data;
                    throw e;
                }
            },
            async loadPage(dir,page,pageSize){
                try {
                    const response = await this.$http.get(this.loadPageUrl,{params:{id:dir.id,page:page-1,pageSize:pageSize}});
                    return  response.data.parameter;
                }catch (e) {
                    console.log(e);
                    let err = e;
                    if(err.response&&err.response.hasOwnProperty("data"))err = err.response.data;
                    throw e;
                }
            },
            checkoutPage(page,dir,tableData){
                const allDir = tableData.every(meta=>meta.isDir);
                if(allDir) this.tableKey=1;
                else this.tableKey=0;
                this.fixedSize = !allDir;
                this.fixedType = !allDir;
                this.fixedDescription = allDir;
            },
            async changeFileMeta(id,targetMeta){
                const formData = new FormData();
                const NAME_KEY = "name",DES_KEY = "description";
                if(targetMeta.name !== targetMeta.origin.name) formData.append(NAME_KEY,targetMeta.name);
                if(targetMeta.description !==targetMeta.origin.description) formData.append(DES_KEY,targetMeta.description);
                formData.append("id",id);
                try {
                    await this.$http.put(this.changeFileUrl,formData);
                }catch (e) {
                    console.log(e);
                    let err = e;
                    if(err.response&&err.response.hasOwnProperty("data"))err = err.response.data;
                    throw e;
                }
                return null;
            },
            async mkdir(targetDir,name,description){
                const formData = new FormData();
                formData.append("parentId",targetDir.id);
                formData.append("name",name);
                formData.append("description",description);
                try {
                    await this.$http.post(this.makeDirectoryUrl,formData);
                }catch (e) {
                    console.log(e);
                    let err = e;
                    if(err.response&&err.response.hasOwnProperty("data"))err = err.response.data;
                    throw e;
                }
                return null;
            },
            async uploadMethod(file,parentDir,description){
                let formData = new FormData();
                formData.append("file", file.file);
                formData.append("parentId",parentDir.id);
                if(description) formData.append("description",description);
                let source = this.$http.CancelToken.source();
                file.file.cancelSource = source;
                this.$http({
                    url: this.uploadUrl,
                    method: 'post',
                    data: formData,
                    //上传进度
                    onUploadProgress: (progressEvent) => {
                        let num = progressEvent.loaded / progressEvent.total * 100 | 0;  //百分比
                        file.onProgress({percent: num})     //进度条
                    },
                    cancelToken:source.token,
                    timeout: -1,
                }).then(data => {
                    file.onSuccess(data); //上传成功(打钩的小图标)
                }).catch(err=>{
                    file.onError(err);
                });
            },
            async deleteFile(file){
                try{
                    await this.$http.delete(`${this.deleteUrl}/${file.id}`);
                }catch (e) {
                    console.log(e);
                    let err = e;
                    if(err.response&&err.response.hasOwnProperty("data"))err = err.response.data;
                    throw e;
                }
            },
            downloadFile(file){
                const extName = file.ext?'.'+file.ext:'';
                window.open(`${this.$http.defaults.baseURL}${this.downloadUrl}/${file.id}${extName}`)
            },
            async searchFile(dir,page,pageSize){
                try {
                    const response = await this.$http.get(this.searchFilesUrl,{
                        params:{name:dir.searchName,parentId:dir.searchDir.id,page:page-1,pageSize:pageSize}
                    });
                    return  response.data.parameter;
                }catch (e) {
                    console.log(e);
                    let err = e;
                    if(err.response&&err.response.hasOwnProperty("data"))err = err.response.data;
                    throw e;
                }
            },
            async searchMeta(name,dir){
                try {
                    const response = await this.$http.get(this.searchMetaUrl,{
                        params:{name:name,parentId:dir.id}
                    });
                    return  response.data.parameter;
                }catch (e) {
                    let err = e;
                    if(err.response&&err.response.hasOwnProperty("data"))err = err.response.data;
                    throw e;
                }
            },
            async searchPreview(queryString,dir,token){
                let arr = null;
                try {
                    const response = await this.$http.get(this.searchFilesUrl,{
                        params:{name:queryString,parentId:dir.id,page:0,pageSize:6},
                        cancelToken:token
                    });
                    arr = response.data.parameter;
                }catch (e) {
                    let err = e;
                    if(err.response&&err.response.hasOwnProperty("data"))err = err.response.data;
                    throw e;
                }
                if(!Array.isArray(arr)) throw new Error("与服务器沟通失败。");
                let ans = [],hash={};
                arr.forEach(file=>{
                    if(!hash.hasOwnProperty(file.name)){
                        ans.push({name:file.name});
                        hash[file.name]=null;
                    }
                });
                return ans;
            },
            previewSource(file){
                const extName = file.ext?'.'+file.ext:'';
                return `${this.$http.defaults.baseURL}${this.downloadUrl}/${file.id}${extName}`;
            },
            async loadFileMeta(id){
                try {
                    const response = await this.$http.get(`${this.loadFileMetaUrl}/${id}`);
                    return response.data.parameter;
                }catch (e) {
                    let err = e;
                    if(err.response&&err.response.hasOwnProperty("data"))err = err.response.data;
                    throw e;
                }
            },
        }
    }
</script>

<style scoped>
</style>
